home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / psd.zip / PRIMITIV.SCM < prev    next >
Text File  |  1992-07-09  |  25KB  |  795 lines

  1. ;;;;
  2. ;;;; primitives.scm 1.7
  3. ;;;;
  4. ;;;; psd -- a portable Scheme debugger, version 1.0
  5. ;;;; Copyright (C) 1992 Pertti Kellomaki, pk@cs.tut.fi
  6.  
  7. ;;;; This program is free software; you can redistribute it and/or modify
  8. ;;;; it under the terms of the GNU General Public License as published by
  9. ;;;; the Free Software Foundation; either version 1, or (at your option)
  10. ;;;; any later version.
  11.  
  12. ;;;; This program is distributed in the hope that it will be useful,
  13. ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;;;; GNU General Public License for more details.
  16.  
  17. ;;;; You should have received a copy of the GNU General Public License
  18. ;;;; along with this program; if not, write to the Free Software
  19. ;;;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20. ;;;; See file COPYING in the psd distribution.
  21.  
  22. ;;;; 
  23. ;;;; Written by Pertti Kellomaki, pk@cs.tut.fi
  24. ;;;;
  25. ;;;; This file contains the parts of the runtime support that have to
  26. ;;;; know about the primitive procedures in the interpreter. This file
  27. ;;;; only knows about the primitives listed as essential in the R4RS.
  28. ;;;; If you want to add other primitives found in a particular
  29. ;;;; implementation, add them in this file.
  30.  
  31. ;;;
  32. ;;; Originally only psd globals and R4RS essentials are visible.
  33. ;;; 
  34.  
  35. (define psd-global-symbol-accessors
  36.   (list (lambda (psd-temp)
  37.       (case psd-temp
  38.  
  39.         ;; Put additional global symbols here. For example, to
  40.         ;; make the symbol list-tail visible, add the line
  41.         ;; ((list-tail) `(,list-tail))
  42.  
  43.         ;; r4rs essentials
  44.         ((*) `(,*))
  45.         ((+) `(,+))
  46.         ((-) `(,-))
  47.         ((/) `(,/))
  48.         ((<) `(,<))
  49.         ((<=) `(,<=))
  50.         ((=) `(,=))
  51.         ((>) `(,>))
  52.         ((>=) `(,>=))
  53.         ((abs) `(,abs))
  54.         ((append) `(,append))
  55.         ((apply) `(,apply))
  56.         ((assoc) `(,assoc))
  57.         ((assq) `(,assq))
  58.         ((assv) `(,assv))
  59.         ((boolean?) `(,boolean?))
  60.         ((caaaar) `(,caaaar))
  61.         ((caaadr) `(,caaadr))
  62.         ((caaar) `(,caaar))
  63.         ((caadar) `(,caadar))
  64.         ((caaddr) `(,caaddr))
  65.         ((caadr) `(,caadr))
  66.         ((caar) `(,caar))
  67.         ((cadaar) `(,cadaar))
  68.         ((cadadr) `(,cadadr))
  69.         ((cadar) `(,cadar))
  70.         ((caddar) `(,caddar))
  71.         ((cadddr) `(,cadddr))
  72.         ((caddr) `(,caddr))
  73.         ((cadr) `(,cadr))
  74.         ((call-with-current-continuation) `(,call-with-current-continuation))
  75.         ((call-with-input-file) `(,call-with-input-file))
  76.         ((call-with-output-file) `(,call-with-output-file))
  77.         ((car) `(,car))
  78.         ((cdaaar) `(,cdaaar))
  79.         ((cdaadr) `(,cdaadr))
  80.         ((cdaar) `(,cdaar))
  81.         ((cdadar) `(,cdadar))
  82.         ((cdaddr) `(,cdaddr))
  83.         ((cdadr) `(,cdadr))
  84.         ((cdar) `(,cdar))
  85.         ((cddaar) `(,cddaar))
  86.         ((cddadr) `(,cddadr))
  87.         ((cddar) `(,cddar))
  88.         ((cdddar) `(,cdddar))
  89.         ((cddddr) `(,cddddr))
  90.         ((cdddr) `(,cdddr))
  91.         ((cddr) `(,cddr))
  92.         ((cdr) `(,cdr))
  93.         ((ceiling) `(,ceiling))
  94.         ((char->integer) `(,char->integer))
  95.         ((char-alphabetic?) `(,char-alphabetic?))
  96.         ((char-ci<=?) `(,char-ci<=?))
  97.         ((char-ci<?) `(,char-ci<?))
  98.         ((char-ci=?) `(,char-ci=?))
  99.         ((char-ci>=?) `(,char-ci>=?))
  100.         ((char-ci>?) `(,char-ci>?))
  101.         ((char-downcase) `(,char-downcase))
  102.         ((char-lower-case?) `(,char-lower-case?))
  103.         ((char-numeric?) `(,char-numeric?))
  104.         ((char-upcase) `(,char-upcase))
  105.         ((char-upper-case?) `(,char-upper-case?))
  106.         ((char-whitespace?) `(,char-whitespace?))
  107.         ((char<=?) `(,char<=?))
  108.         ((char<?) `(,char<?))
  109.         ((char=?) `(,char=?))
  110.         ((char>=?) `(,char>=?))
  111.         ((char>?) `(,char>?))
  112.         ((char?) `(,char?))
  113.         ((close-input-port) `(,close-input-port))
  114.         ((close-output-port) `(,close-output-port))
  115.         ((complex?) `(,complex?))
  116.         ((cons) `(,cons))
  117.         ((current-input-port) `(,current-input-port))
  118.         ((current-output-port) `(,current-output-port))
  119.         ((display) `(,display))
  120.         ((eof-object?) `(,eof-object?))
  121.         ((eq?) `(,eq?))
  122.         ((equal?) `(,equal?))
  123.         ((eqv?) `(,eqv?))
  124.         ((even?) `(,even?))
  125.         ((exact?) `(,exact?))
  126.         ((floor) `(,floor))
  127.         ((for-each) `(,for-each))
  128.         ((gcd) `(,gcd))
  129.         ((inexact?) `(,inexact?))
  130.         ((input-port?) `(,input-port?))
  131.         ((integer->char) `(,integer->char))
  132.         ((integer?) `(,integer?))
  133.         ((lcm) `(,lcm))
  134.         ((length) `(,length))
  135.         ((list) `(,list))
  136.         ((list->string) `(,list->string))
  137.         ((list->vector) `(,list->vector))
  138.         ((list-ref) `(,list-ref))
  139.         ((list?) `(,list?))
  140.         ((load) `(,load))
  141.         ((make-string) `(,make-string))
  142.         ((make-vector) `(,make-vector))
  143.         ((map) `(,map))
  144.         ((max) `(,max))
  145.         ((member) `(,member))
  146.         ((memq) `(,memq))
  147.         ((memv) `(,memv))
  148.         ((min) `(,min))
  149.         ((modulo) `(,modulo))
  150.         ((negative?) `(,negative?))
  151.         ((newline) `(,newline))
  152.         ((not) `(,not))
  153.         ((null?) `(,null?))
  154.         ((number->string) `(,number->string))
  155.         ((number?) `(,number?))
  156.         ((odd?) `(,odd?))
  157.         ((open-input-file) `(,open-input-file))
  158.         ((open-output-file) `(,open-output-file))
  159.         ((output-port?) `(,output-port?))
  160.         ((pair?) `(,pair?))
  161.         ((peek-char) `(,peek-char))
  162.         ((positive?) `(,positive?))
  163.         ((procedure?) `(,procedure?))
  164.         ((quotient) `(,quotient))
  165.         ((rational?) `(,rational?))
  166.         ((read) `(,read))
  167.         ((read-char) `(,read-char))
  168.         ((real?) `(,real?))
  169.         ((remainder) `(,remainder))
  170.         ((reverse) `(,reverse))
  171.         ((round) `(,round))
  172.         ((set-car!) `(,set-car!))
  173.         ((set-cdr!) `(,set-cdr!))
  174.         ((string) `(,string))
  175.         ((string->list) `(,string->list))
  176.         ((string->number) `(,string->number))
  177.         ((string->symbol) `(,string->symbol))
  178.         ((string-append) `(,string-append))
  179.         ((string-ci<=?) `(,string-ci<=?))
  180.         ((string-ci<?) `(,string-ci<?))
  181.         ((string-ci=?) `(,string-ci=?))
  182.         ((string-ci>=?) `(,string-ci>=?))
  183.         ((string-ci>?) `(,string-ci>?))
  184.         ((string-length) `(,string-length))
  185.         ((string-ref) `(,string-ref))
  186.         ((string-set!) `(,string-set!))
  187.         ((string<=?) `(,string<=?))
  188.         ((string<?) `(,string<?))
  189.         ((string=?) `(,string=?))
  190.         ((string>=?) `(,string>=?))
  191.         ((string>?) `(,string>?))
  192.         ((string?) `(,string?))
  193.         ((substring) `(,substring))
  194.         ((symbol->string) `(,symbol->string))
  195.         ((symbol?) `(,symbol?))
  196.         ((truncate) `(,truncate))
  197.         ((vector) `(,vector))
  198.         ((vector->list) `(,vector->list))
  199.         ((vector-length) `(,vector-length))
  200.         ((vector-ref) `(,vector-ref))
  201.         ((vector-set!) `(,vector-set!))
  202.         ((vector?) `(,vector?))
  203.         ((write) `(,write))
  204.         ((write-char) `(,write-char))
  205.         ((zero?) `(,zero?))
  206.  
  207.         ;; psd globals
  208.         ((psd-set-breakpoint) `(,psd-set-breakpoint))
  209.         ((psd-reset) `(,psd-reset))
  210.         ((*psd-previous-line*) `(,*psd-previous-line*))
  211.         ((*psd-stepping-by-line*) `(,*psd-stepping-by-line*))
  212.         ((*psd-coming-from-line*) `(,*psd-coming-from-line*))
  213.         ((*psd-break?*) `(,*psd-break?*))
  214.         ((*psd-breakpoints*) `(,*psd-breakpoints*)) 
  215.         (else #f)))))
  216.  
  217. (define psd-global-symbol-setters
  218.   (list (lambda (psd-temp psd-temp2)
  219.       (case psd-temp 
  220.  
  221.         ;; You can also put additional global symbols here.
  222.  
  223.         ;; psd globals
  224.         ((psd-set-breakpoint) (set! psd-set-breakpoint psd-temp2)) 
  225.         ((psd-reset) (set! psd-reset psd-temp2)) 
  226.         ((*psd-previous-line*) (set! *psd-previous-line* psd-temp2)) 
  227.         ((*psd-stepping-by-line*) (set! *psd-stepping-by-line* psd-temp2)) 
  228.         ((*psd-coming-from-line*) (set! *psd-coming-from-line* psd-temp2)) 
  229.         ((*psd-break?*) (set! *psd-break?* psd-temp2)) 
  230.         ((*psd-breakpoints*) (set! *psd-breakpoints* psd-temp2))
  231.         (else #f)))))
  232.  
  233. ;;;
  234. ;;; The scope is determined using a scheme similar to accessing variables.
  235. ;;; 
  236.  
  237.  
  238. (define (psd-context) '())
  239.  
  240.  
  241.  
  242. ;;;
  243. ;;; In order to be able to catch runtime type errors and calls with
  244. ;;; wrong number of arguments, each procedure call is made via
  245. ;;; psd-apply. It checks if the procedure to be applied is found in
  246. ;;; the list of primitive proceduers. If it is, the number of arguments 
  247. ;;; and their types are checked using the information in the list.
  248. ;;; The format of the list is
  249. ;;;
  250. ;;; (... (procedure (number-of-args assertion ...) ...) ...)
  251. ;;;
  252.  
  253. ;;; Each sublist specifies one allowable case of number of arguments.
  254. ;;; The number of args can be a number or the symbol &rest meaning an
  255. ;;; arbitrary number of arguments. Each assertion is a procedure of
  256. ;;; one argument. It is called with a list of the values of each
  257. ;;; subexpression in the procedure call. Most of the assertions are
  258. ;;; expressed with the procedure assert, that takes the argument
  259. ;;; position to check and a predicate to apply to it. The assertions
  260. ;;; work "backward", returning false, if the call can be made. If an
  261. ;;; assertion fails (the call would result in a run time error), it
  262. ;;; returns a string to be displayed.
  263.  
  264. ;;;
  265. ;;; If a run time error would occur, the debugger is invoked with an
  266. ;;; appropriate message given to the user.
  267. ;;;
  268. ;;; Bound checking is not yet done, but it might be useful for eg.
  269. ;;; list-ref, vector-ref etc.
  270. ;;;
  271. ;;; I have also cheated a bit in places like for-each, where only the
  272. ;;; first argument is checked for. I have tried to indicate these with
  273. ;;; "needs work".
  274. ;;; 
  275.  
  276. (define psd-apply
  277.  
  278.   (let ((+ +) (= =) (apply apply) (assoc assoc) (assq assq)
  279.           (cadr cadr) (car car) (cdr cdr) (cons cons)
  280.           (display display) (eq? eq?) (equal? equal?)
  281.           (for-each for-each) (length length)
  282.           (list->string list->string) (list-ref list-ref)
  283.           (map map) (newline newline) (not not) (null? null?)
  284.           (number->string number->string) (pair? pair?)
  285.           (reverse reverse)
  286.           (string-append string-append) (symbol->string symbol->string))
  287.     (letrec
  288.  
  289.     ;; Names of all the essential procedures
  290.     ((r4rs-names
  291.       `(
  292.         ;; You can add additional procedures here.
  293.  
  294.         
  295.         ;; R4RS essentials
  296.         (,* *) 
  297.         (,+ +) 
  298.         (,- -) 
  299.         (,/ /) 
  300.         (,< <) 
  301.         (,<= <=) 
  302.         (,= =) 
  303.         (,> >) 
  304.         (,>= >=)
  305.         (,abs abs) 
  306.         (,append append) 
  307.         (,apply apply) 
  308.         (,assoc assoc) 
  309.         (,assq assq)
  310.         (,assv assv) 
  311.         (,boolean? boolean?) 
  312.         (,caaaar caaaar) 
  313.         (,caaadr caaadr)
  314.         (,caaar caaar) 
  315.         (,caadar caadar) 
  316.         (,caaddr caaddr) 
  317.         (,caadr caadr) 
  318.         (,caar caar)
  319.         (,cadaar cadaar) 
  320.         (,cadadr cadadr) 
  321.         (,cadar cadar) 
  322.         (,caddar caddar)
  323.         (,cadddr cadddr) 
  324.         (,caddr caddr) 
  325.         (,cadr cadr)
  326.         (,call-with-current-continuation call-with-current-continuation)
  327.         (,call-with-input-file call-with-input-file)
  328.         (,call-with-output-file call-with-output-file)
  329.         (,car car) 
  330.         (,cdaaar cdaaar) 
  331.         (,cdaadr cdaadr) 
  332.         (,cdaar cdaar) 
  333.         (,cdadar cdadar)
  334.         (,cdaddr cdaddr) 
  335.         (,cdadr cdadr) 
  336.         (,cdar cdar) 
  337.         (,cddaar cddaar) 
  338.         (,cddadr cddadr)
  339.         (,cddar cddar) 
  340.         (,cdddar cdddar) 
  341.         (,cddddr cddddr) 
  342.         (,cdddr cdddr) 
  343.         (,cddr cddr)
  344.         (,cdr cdr) 
  345.         (,ceiling ceiling) 
  346.         (,char->integer char->integer)
  347.         (,char-alphabetic? char-alphabetic?) 
  348.         (,char-ci<=? char-ci<=?) 
  349.         (,char-ci<? char-ci<?) 
  350.         (,char-ci=? char-ci=?) 
  351.         (,char-ci>=? char-ci>=?)
  352.         (,char-ci>? char-ci>?) 
  353.         (,char-downcase char-downcase) 
  354.         (,char-lower-case? char-lower-case?)
  355.         (,char-numeric? char-numeric?)
  356.         (,char-upcase char-upcase)
  357.         (,char-upper-case? char-upper-case?)
  358.         (,char-whitespace? char-whitespace?)
  359.         (,char<=? char<=?)
  360.         (,char<? char<?)
  361.         (,char=? char=?)
  362.         (,char>=? char>=?)
  363.         (,char>? char>?)
  364.         (,char? char?)
  365.         (,close-input-port close-input-port)
  366.         (,close-output-port close-output-port)
  367.         (,complex? complex?)
  368.         (,cons cons)
  369.         (,current-input-port current-input-port)
  370.         (,current-output-port current-output-port)
  371.         (,display display)
  372.         (,eof-object? eof-object?)
  373.         (,eq? eq?)
  374.         (,equal? equal?)
  375.         (,eqv? eqv?)
  376.         (,even? even?)
  377.         (,exact? exact?)
  378.         (,floor floor)
  379.         (,for-each for-each)
  380.         (,gcd gcd)
  381.         (,inexact? inexact?)
  382.         (,input-port? input-port?)
  383.         (,integer->char integer->char)
  384.         (,integer? integer?)
  385.         (,lcm lcm)
  386.         (,length length)
  387.         (,list list)
  388.         (,list->string list->string)
  389.         (,list->vector list->vector)
  390.         (,list-ref list-ref)
  391.         (,list? list?)
  392.         (,load load)
  393.         (,make-string make-string)
  394.         (,make-vector make-vector)
  395.         (,map map)
  396.         (,max max)
  397.         (,member member)
  398.         (,memq memq)
  399.         (,memv memv)
  400.         (,min min)
  401.         (,modulo modulo)
  402.         (,negative? negative?)
  403.         (,newline newline)
  404.         (,not not)
  405.         (,null? null?)
  406.         (,number->string number->string)
  407.         (,number? number?)
  408.         (,odd? odd?)
  409.         (,open-input-file open-input-file)
  410.         (,open-output-file open-output-file)
  411.         (,output-port? output-port?)
  412.         (,pair? pair?)
  413.         (,peek-char peek-char)
  414.         (,positive? positive?)
  415.         (,procedure? procedure?)
  416.         (,quotient quotient)
  417.         (,rational? rational?)
  418.         (,read read)
  419.         (,read-char read-char)
  420.         (,real? real?)
  421.         (,remainder remainder)
  422.         (,reverse reverse)
  423.         (,round round)
  424.         (,set-car! set-car!)
  425.         (,set-cdr! set-cdr!)
  426.         (,string string)
  427.         (,string->list string->list)
  428.         (,string->number string->number)
  429.         (,string->symbol string->symbol)
  430.         (,string-append string-append)
  431.         (,string-ci<=? string-ci<=?)
  432.         (,string-ci<? string-ci<?)
  433.         (,string-ci=? string-ci=?)
  434.         (,string-ci>=? string-ci>=?)
  435.         (,string-ci>? string-ci>?)
  436.         (,string-length string-length)
  437.         (,string-ref string-ref)
  438.         (,string-set! string-set!)
  439.         (,string<=? string<=?)
  440.         (,string<? string<?)
  441.         (,string=? string=?)
  442.         (,string>=? string>=?)
  443.         (,string>? string>?)
  444.         (,string? string?)
  445.         (,substring substring)
  446.         (,symbol->string symbol->string)
  447.         (,symbol? symbol?)
  448.         (,truncate truncate)
  449.         (,vector vector)
  450.         (,vector->list vector->list)
  451.         (,vector-length vector-length)
  452.         (,vector-ref vector-ref)
  453.         (,vector-set! vector-set!)
  454.         (,vector? vector?)
  455.         (,write write)
  456.         (,write-char write-char)
  457.         (,zero? zero?)))
  458.  
  459.  
  460.      ;;
  461.      ;; Check that the c...r operation can be made safely.
  462.      ;;
  463.      (successive-pairs
  464.       (lambda operations
  465.         (lambda (combination)
  466.           (let loop ((operations (reverse operations))
  467.              (trail '())
  468.              (this (cadr combination)))
  469.         (cond ((null? operations)
  470.                #f)
  471.               ((not (pair? this))
  472.                (if (null? trail)
  473.                "argument not a pair"
  474.                (string-append "c"
  475.                       (list->string (reverse trail))
  476.                       "r of argument not a pair")))
  477.               (else
  478.                (loop (cdr operations)
  479.                  (cons (if (eq? car (car operations))
  480.                        #\a
  481.                        #\d)
  482.                    trail)
  483.                  ((car operations) this))))))))
  484.  
  485.      ;;
  486.      ;; Check the i'th position of args
  487.      ;;
  488.  
  489.      (assert
  490.       (lambda (i predicate? . predicate-name)
  491.         (lambda (combination)
  492.           (if (equal? i 'all)
  493.           (let loop ((args (cdr combination))
  494.                  (failures '())
  495.                  (i 1))
  496.             (cond
  497.  
  498.              ;; no failures
  499.              ((and (null? args)
  500.                (null? failures))
  501.               #f)
  502.  
  503.              ;; there were failures
  504.              ((null? args)
  505.               (string-append (if (= (length failures) 1)
  506.                      "argument at position "
  507.                      "arguments at positions ")
  508.                      (apply string-append
  509.                         (map
  510.                          (lambda (n)
  511.                            (string-append
  512.                         (number->string n)
  513.                         " "))
  514.                          (reverse failures)))
  515.                      (if (null? predicate-name)
  516.                      (string-append
  517.                       "did not satisfy predicate "
  518.                       (procedure-name predicate?))
  519.                      (car predicate-name))))
  520.              (else
  521.               (loop (cdr args)
  522.                 (if (predicate? (car args))
  523.                 failures
  524.                 (cons i failures))
  525.                 (+ i 1)))))
  526.         
  527.           (let ((result (predicate? (list-ref combination i))))
  528.             (if result
  529.             #f
  530.             (string-append "argument "
  531.                        (number->string i)
  532.                        (if (null? predicate-name)
  533.                        (string-append
  534.                         " did not satisfy predicate "
  535.                         (procedure-name predicate?))
  536.                        (car predicate-name)))))))))
  537.  
  538.      ;;
  539.      ;; Get the name of a procedure
  540.      ;;
  541.  
  542.      (procedure-name
  543.       (lambda (proc)
  544.         (let ((entry (assoc proc r4rs-names)))
  545.           (if entry
  546.           (symbol->string (cadr entry))
  547.           "#[unknown primitive procedure]")))))
  548.  
  549.      (let
  550.          ((primitive-procedures
  551.            `(
  552.          ;; You can add additional primitive procedures here.
  553.           
  554.  
  555.          ;; R4RS essentials
  556.          (,* (&rest ,(assert 'all number?)))
  557.          (,+ (&rest ,(assert 'all number?)))
  558.          (,- (&rest ,(assert 'all number?)))
  559.          (,/ (&rest ,(assert 'all number?)))
  560.          (,< (&rest ,(assert 'all number?)))
  561.          (,<= (&rest ,(assert 'all number?)))
  562.          (,= (&rest ,(assert 'all number?)))
  563.          (,> (&rest ,(assert 'all number?)))
  564.          (,>= (&rest ,(assert 'all number?)))
  565.          (,abs (1 ,(assert 1 number?)))
  566.          (,append (&rest ,(assert 'all pair?)))
  567.          (,apply (&rest ,(assert 1 procedure?)))
  568.          (,assoc (2 ,(assert 2 pair?)))
  569.          (,assq (2 ,(assert 2 pair?)))
  570.          (,assv (2 ,(assert 2 pair?)))
  571.          (,boolean? (1))
  572.          (,caaaar (1 ,(successive-pairs car car car car)))
  573.          (,caaadr (1 ,(successive-pairs car car car cdr)))
  574.          (,caaar (1 ,(successive-pairs car car car)))
  575.          (,caadar (1 ,(successive-pairs car car cdr car)))
  576.          (,caaddr (1 ,(successive-pairs car car cdr cdr)))
  577.          (,caadr (1 ,(successive-pairs car car cdr)))
  578.          (,caar (1 ,(successive-pairs car car)))
  579.          (,cadaar (1 ,(successive-pairs car cdr car car)))
  580.          (,cadadr (1 ,(successive-pairs car cdr car cdr)))
  581.          (,cadar (1 ,(successive-pairs car cdr car)))
  582.          (,caddar (1 ,(successive-pairs car cdr cdr car)))
  583.          (,cadddr (1 ,(successive-pairs car cdr cdr cdr)))
  584.          (,caddr (1 ,(successive-pairs car cdr cdr)))
  585.          (,cadr (1 ,(successive-pairs car cdr)))
  586.          (,call-with-current-continuation (1 ,(assert 1 procedure?)))
  587.          (,call-with-input-file (2 ,(assert 1 string?) ,(assert 2 procedure?)))
  588.          (,call-with-output-file (2 ,(assert 1 string?) ,(assert 2 procedure?)))
  589.          (,car (1 ,(assert 1 pair?)))
  590.          (,cdaaar (1 ,(successive-pairs cdr car car car)))
  591.          (,cdaadr (1 ,(successive-pairs cdr car car cdr)))
  592.          (,cdaar (1 ,(successive-pairs cdr car car)))
  593.          (,cdadar (1 ,(successive-pairs cdr car cdr car)))
  594.          (,cdaddr (1 ,(successive-pairs cdr car cdr cdr)))
  595.          (,cdadr (1 ,(successive-pairs cdr car cdr)))
  596.          (,cdar (1 ,(successive-pairs cdr car)))
  597.          (,cddaar (1 ,(successive-pairs cdr cdr car car)))
  598.          (,cddadr (1 ,(successive-pairs cdr cdr car cdr)))
  599.          (,cddar (1 ,(successive-pairs cdr cdr car)))
  600.          (,cdddar (1 ,(successive-pairs cdr cdr cdr car)))
  601.          (,cddddr (1 ,(successive-pairs cdr cdr cdr cdr)))
  602.          (,cdddr (1 ,(successive-pairs cdr cdr cdr)))
  603.          (,cddr (1 ,(successive-pairs cdr cdr)))
  604.          (,cdr (1 ,(assert 1 pair?)))
  605.          (,ceiling (1 ,(assert 1 number?)))
  606.          (,char->integer (1 ,(assert 1 char?)))
  607.          (,char-alphabetic? (1 ,(assert 1 char?)))
  608.          (,char-ci<=? (&rest ,(assert 'all char?)))
  609.          (,char-ci<? (&rest ,(assert 'all char?)))
  610.          (,char-ci=? (&rest ,(assert 'all char?)))
  611.          (,char-ci>=? (&rest ,(assert 'all char?)))
  612.          (,char-ci>? (&rest ,(assert 'all char?)))
  613.          (,char-downcase (1 ,(assert 1 char?)))
  614.          (,char-lower-case? (1 ,(assert 1 char?)))
  615.          (,char-numeric? (1 ,(assert 1 char?)))
  616.          (,char-upcase (1 ,(assert 1 char?)))
  617.          (,char-upper-case? (1 ,(assert 1 char?)))
  618.          (,char-whitespace? (1 ,(assert 1 char?)))
  619.          (,char<=? (&rest ,(assert 'all char?)))
  620.          (,char<? (&rest ,(assert 'all char?)))
  621.          (,char=? (&rest ,(assert 'all char?)))
  622.          (,char>=? (&rest ,(assert 'all char?)))
  623.          (,char>? (&rest ,(assert 'all char?)))
  624.          (,char? (1))
  625.          (,close-input-port (1 ,(assert 1 input-port?)))
  626.          (,close-output-port (1 ,(assert 1 output-port?)))
  627.          (,complex? (1))
  628.          (,cons (2))
  629.          (,current-input-port (0))
  630.          (,current-output-port (0))
  631.          (,display (0) (1 ,(assert 1 output-port?)))
  632.          (,eof-object? (1))
  633.          (,eq? (2))
  634.          (,equal? (2))
  635.          (,eqv? (2))
  636.          (,even? (1 ,(assert 1 integer?)))
  637.          (,exact? (1 ,(assert 1 number?)))
  638.          (,floor (1 ,(assert 1 number?)))
  639.          (,for-each ('&args ,(assert 1 procedure?))) ; needs work
  640.          (,gcd (&rest ,(assert 'all integer?)))
  641.          (,inexact? (1 ,(assert 1 number?)))
  642.          (,input-port? (1))
  643.          (,integer->char (1 ,(assert 1 integer?)))
  644.          (,integer? (1))
  645.          (,lcm (&rest ,(assert 'all integer?)))
  646.          (,length (1 ,(assert 1 pair?)))
  647.          (,list (&rest))
  648.          (,list->string (1 ,(assert 1 pair?))) ; needs work
  649.          (,list->vector (1 ,(assert 1 pair?)))
  650.          (,list-ref (2 ,(assert 1 pair?) ,(assert 2 integer?)))
  651.          (,list? (1))
  652.          (,load (1 ,(assert 1 string?)))
  653.          (,make-string (1 ,(assert 1 integer?)) (2 ,(assert 1 integer?) ,(assert 2 char?)))
  654.          (,make-vector (1 ,(assert 1 integer?)) (2 ,(assert 1 integer?)))
  655.          (,map (&rest ,(assert 1 procedure?)))
  656.          (,max (&rest ,(assert 'all number?)))
  657.          (,member (2 ,(assert 2 pair?)))
  658.          (,memq (2 ,(assert 2 pair?)))
  659.          (,memv (2 ,(assert 2 pair?)))
  660.          (,min (&rest ,(assert 'all number?)))
  661.          (,modulo (2 ,(assert 'all integer?)))
  662.          (,negative? (1 ,(assert 1 number?)))
  663.          (,newline (0) (1 ,(assert 1 output-port?)))
  664.          (,not (1))
  665.          (,null? (1))
  666.          (,number->string (1 ,(assert 1 number?)) (2 ,(assert 1 number?) ,(assert 2 (lambda (n) (member n '(2 8 10 16))))))
  667.          (,number? (1))
  668.          (,odd? (1 ,(assert 1 integer?)))
  669.          (,open-input-file (1 ,(assert 1 string?)))
  670.          (,open-output-file (1 ,(assert 1 string?)))
  671.          (,output-port? (1))
  672.          (,pair? (1))
  673.          (,peek-char (1 ,(assert 1 input-port?)))
  674.          (,positive? (1 ,(assert 1 number?)))
  675.          (,procedure? (1))
  676.          (,quotient (2 ,(assert 'all integer?)))
  677.          (,rational? (1))
  678.          (,read (0) (1 ,(assert 1 input-port?)))
  679.          (,read-char (1 ,(assert 1 input-port?)))
  680.          (,real? (1))
  681.          (,remainder (2 ,(assert 'all integer?)))
  682.          (,reverse (1 ,(assert 1 pair?)))
  683.          (,round (1 ,(assert 1 number?)))
  684.          (,set-car! (2 ,(assert 1 pair?)))
  685.          (,set-cdr! (2 ,(assert 1 pair?)))
  686.          (,string (&rest ,(assert 'all char?)))
  687.          (,string->list (1 ,(assert 1 string)))
  688.          (,string->number (1 ,(assert 1 string?)) (2 ,(assert 1 string?) ,(assert 2 (lambda (n) (member n '(2 8 10 16))))))
  689.          (,string->symbol (1 ,(assert 1 string?)))
  690.          (,string-append (&rest ,(assert 'all string?)))
  691.          (,string-ci<=? (&rest ,(assert 'all string?)))
  692.          (,string-ci<? (&rest ,(assert 'all string?)))
  693.          (,string-ci=? (&rest ,(assert 'all string?)))
  694.          (,string-ci>=? (&rest ,(assert 'all string?)))
  695.          (,string-ci>? (&rest ,(assert 'all string?)))
  696.          (,string-length (1 ,(assert 1 string?)))
  697.          (,string-ref (2 ,(assert 1 string?) ,(assert 2 integer?)))
  698.          (,string-set! (3 ,(assert 1 string?) ,(assert 2 integer?) ,(assert 3 char?)))
  699.          (,string<=? (&rest ,(assert 'all string?)))
  700.          (,string<? (&rest ,(assert 'all string?)))
  701.          (,string=? (&rest ,(assert 'all string?)))
  702.          (,string>=? (&rest ,(assert 'all string?)))
  703.          (,string>? (&rest ,(assert 'all string?)))
  704.          (,string? (1))
  705.          (,substring (3 ,(assert 1 string) ,(assert 2 integer?) ,(assert 3 integer?)))
  706.          (,symbol->string (1 ,(assert 1 symbol?)))
  707.          (,symbol? (1))
  708.          (,truncate (1 ,(assert 1 number?)))
  709.          (,vector (&rest))
  710.          (,vector->list (1 ,(assert 1 vector?)))
  711.          (,vector-length (1 ,(assert 1 vector?)))
  712.          (,vector-ref (2 ,(assert 1 vector?) ,(assert 2 integer?)))
  713.          (,vector-set! (3 ,(assert 1 vector?) ,(assert 2 integer?)))
  714.          (,vector? (1))
  715.          (,write (0) (1 ,(assert 1 output-port?)))
  716.          (,write-char (0) (1 ,(assert 1 output-port?)))
  717.          (,zero? (1 ,(assert 1 number?)) (name zero?)))))
  718.  
  719.        (lambda (combination . debug-arguments)
  720.          (if (assq (car combination) primitive-procedures)
  721.  
  722.  
  723.          ;; This is a primitive, check number of args and their types
  724.          (let ((entry (cdr (assq (car combination)
  725.                      primitive-procedures))))
  726.  
  727.  
  728.            ;; See if there is a subentry for the number of arguments
  729.            ;; in the call.
  730.            (let ((subentry (or (assoc (length (cdr combination))
  731.                           entry)
  732.                        (assoc '&rest
  733.                           entry))))
  734.  
  735.              ;; Check the number of arguments
  736.              (if (not subentry)
  737.  
  738.              ;; There was no subentry for this number of arguments
  739.              (begin
  740.                (display "ERROR: Wrong number of arguments to primitive procedure ")
  741.                (display (procedure-name (car combination)))
  742.                (newline)
  743.                (apply psd-debug debug-arguments))
  744.  
  745.              ;; There was a subentry, check that all the
  746.              ;; assertions given in it are satisfied before
  747.              ;; doing the procedure call
  748.              (begin
  749.                (let loop ((assertions (cdr subentry))
  750.                       (errors '()))
  751.                  (cond
  752.  
  753.                   ;; there were no type errors
  754.                   ((and (null? assertions)
  755.                     (null? errors))
  756.                    (apply (car combination)
  757.                       (cdr combination)))
  758.  
  759.                   ;; all assertions checked, there were type errors
  760.                   ((null? assertions)
  761.                    (display "ERROR: Type error when calling primitive procedure ")
  762.                    (display (procedure-name (car combination)))
  763.                    (newline)
  764.                    (for-each (lambda (str)
  765.                        (display "       ")
  766.                        (display str)
  767.                        (newline))
  768.                      (reverse errors))
  769.                    (apply psd-debug debug-arguments))
  770.  
  771.                   ;; still more to check
  772.                   (else
  773.                    (loop (cdr assertions)
  774.                      (let ((result ((car assertions) combination)))
  775.                        (if result
  776.                        (cons result
  777.                          errors)
  778.                        errors))))))))))
  779.  
  780.          (if (procedure? (car combination))
  781.              
  782.              ;; This is just a normal user procedure or a non-essential
  783.              ;; primitive. Cross your fingers and go!
  784.              (apply (car combination)
  785.                 (cdr combination))
  786.  
  787.              ;; This is not a procedure at all!
  788.              (begin
  789.                (display "ERROR: Attempt to call a non procedural object ")
  790.                (display (car combination))
  791.                (newline)
  792.                (apply psd-debug debug-arguments)))))))))
  793.  
  794.       
  795.